From f49ef1b0a853fee2781f0302278571102fd820df Mon Sep 17 00:00:00 2001 From: robertl Date: Thu, 9 Feb 2006 01:04:13 +0000 Subject: [PATCH] Add concept of optional fields to output in the xSV formats so that unknown fields may be appended if their value is knonwn. Modify Garmin POI format to take advantage of this to display geocaching info. --- gpsbabel/csv_util.c | 27 ++++++++++++++++++++++++++- gpsbabel/csv_util.h | 1 + gpsbabel/internal_styles.c | 7 ++++++- gpsbabel/style/garmin_poi.style | 5 ++++- gpsbabel/xcsv.c | 3 +++ 5 files changed, 40 insertions(+), 3 deletions(-) diff --git a/gpsbabel/csv_util.c b/gpsbabel/csv_util.c index a2ef89346..877851ad1 100644 --- a/gpsbabel/csv_util.c +++ b/gpsbabel/csv_util.c @@ -1105,6 +1105,13 @@ xcsv_waypt_pr(const waypoint *wpt) char *obuff; double lat = wpt->latitude; double lon = wpt->longitude; + /* + * A klunky concept. This should evaluate to true for any + * field if we think we don't have realistic value for it. + * This is used by the 'optional' attribute for suppressing + * fields on output. + */ + int field_is_unknown = 0; fmp = (field_map_t *) elem; @@ -1211,7 +1218,7 @@ xcsv_waypt_pr(const waypoint *wpt) dec_to_human( buff, fmp->printfc, "SN", lat ); } else if (strcmp(fmp->key, "LAT_NMEA") == 0) { - writebuff(buff, fmp->printfc, degrees2ddmm(lat)); + writebuff(buff, fmp->printfc, degrees2ddmm(lat)); } else /* LONGITUDE CONVERSIONS*********************************************/ @@ -1328,43 +1335,54 @@ xcsv_waypt_pr(const waypoint *wpt) if (strcmp(fmp->key, "GEOCACHE_DIFF") == 0) { /* Geocache Difficulty as a double */ writebuff(buff, fmp->printfc, wpt->gc_data.diff / 10.0); + field_is_unknown = !wpt->gc_data.diff; } else if (strcmp(fmp->key, "GEOCACHE_TERR") == 0) { /* Geocache Terrain as a double */ writebuff(buff, fmp->printfc, wpt->gc_data.terr / 10.0); + field_is_unknown = !wpt->gc_data.terr; } else if (strcmp(fmp->key, "GEOCACHE_CONTAINER") == 0) { /* Geocache Container */ writebuff(buff, fmp->printfc, gs_get_container(wpt->gc_data.container)); + field_is_unknown = wpt->gc_data.container == gc_unknown; } else if (strcmp(fmp->key, "GEOCACHE_TYPE") == 0) { /* Geocache Type */ writebuff(buff, fmp->printfc, gs_get_cachetype(wpt->gc_data.type)); + field_is_unknown = wpt->gc_data.type == gt_unknown; } else if (strcmp(fmp->key, "GEOCACHE_HINT") == 0) { writebuff(buff, fmp->printfc, NONULL(wpt->gc_data.hint)); + field_is_unknown = !wpt->gc_data.hint; } else if (strcmp(fmp->key, "GEOCACHE_PLACER") == 0) { writebuff(buff, fmp->printfc, NONULL(wpt->gc_data.placer)); + field_is_unknown = !wpt->gc_data.placer; } else /* GPS STUFF *******************************************************/ if (strcmp(fmp->key, "GPS_HDOP") == 0) { writebuff(buff, fmp->printfc, wpt->hdop); + field_is_unknown = !wpt->hdop; } else if (strcmp(fmp->key, "GPS_VDOP") == 0) { writebuff(buff, fmp->printfc, wpt->vdop); + field_is_unknown = !wpt->vdop; } else if (strcmp(fmp->key, "GPS_PDOP") == 0) { writebuff(buff, fmp->printfc, wpt->pdop); + field_is_unknown = !wpt->pdop; } else if (strcmp(fmp->key, "GPS_SAT") == 0) { writebuff(buff, fmp->printfc, wpt->sat); + field_is_unknown = !wpt->sat; } else if (strcmp(fmp->key, "GPS_FIX") == 0) { char *fix = NULL; switch (wpt->fix) { case fix_unknown: + field_is_unknown = 1; fix = "Unknown"; break; case fix_none: @@ -1392,6 +1410,12 @@ xcsv_waypt_pr(const waypoint *wpt) obuff = csv_stringclean(buff, xcsv_file.badchars); + + if (field_is_unknown && fmp->options & OPTIONS_OPTIONAL) { + goto next; + } + + /* As a special case (pronounced "horrible hack") we allow * ""%s"" to smuggle bad characters through. */ @@ -1401,6 +1425,7 @@ xcsv_waypt_pr(const waypoint *wpt) fprintf (xcsv_file.xcsvfp, "%s", obuff); } +next: xfree(obuff); } diff --git a/gpsbabel/csv_util.h b/gpsbabel/csv_util.h index ef00a5963..c93cc6e9b 100644 --- a/gpsbabel/csv_util.h +++ b/gpsbabel/csv_util.h @@ -75,6 +75,7 @@ xcsv_get_char_from_constant_table(char *key); /* something to map fields to waypts */ #define OPTIONS_NODELIM 1 #define OPTIONS_ABSOLUTE 2 +#define OPTIONS_OPTIONAL 3 typedef struct field_map { queue Q; char * key; diff --git a/gpsbabel/internal_styles.c b/gpsbabel/internal_styles.c index 215cfd626..b0c3376db 100644 --- a/gpsbabel/internal_styles.c +++ b/gpsbabel/internal_styles.c @@ -314,7 +314,12 @@ static char garmin_poi[] = "OFIELD LON_DECIMAL, \"\", \"%08.5f\"\n" "OFIELD LAT_DECIMAL, \"\", \"%08.5f\"\n" "OFIELD SHORTNAME, \"\", \"%-.24s\"\n" +"OFIELD GEOCACHE_TYPE, \"\", \" %-.4s\", \"no_delim_before,optional\"\n" +"OFIELD GEOCACHE_CONTAINER, \"\", \"/%-.4s \", \"no_delim_before,optional\"\n" +"OFIELD GEOCACHE_DIFF, \"\", \"(%3.1f\", \"no_delim_before,optional\"\n" +"OFIELD GEOCACHE_TERR, \"\", \"/%3.1f)\", \"no_delim_before,optional\"\n" "OFIELD DESCRIPTION, \"\", \"%-.50s\"\n" +"# OFIELD GEOCACHE_PLACER, \"\", \" %s\", \"no_delim_before,optional\"\n" ; static char geonet[] = @@ -667,7 +672,7 @@ static char s_and_t[] = "RECORD_DELIMITER NEWLINE\n" "BADCHARS ,\"\n" -"PROLOGUE Name Latitude Longitude Description URL Type Container Diff Terr\n" +"PROLOGUE Name Latitude Longitude Name2 URL Type Container Diff Terr\n" "#\n" "# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" diff --git a/gpsbabel/style/garmin_poi.style b/gpsbabel/style/garmin_poi.style index 3e83c50f2..e15b35bf3 100644 --- a/gpsbabel/style/garmin_poi.style +++ b/gpsbabel/style/garmin_poi.style @@ -27,5 +27,8 @@ IFIELD DESCRIPTION, "", "%s" OFIELD LON_DECIMAL, "", "%08.5f" OFIELD LAT_DECIMAL, "", "%08.5f" OFIELD SHORTNAME, "", "%-.24s" +OFIELD GEOCACHE_TYPE, "", " %-.4s", "no_delim_before,optional" +OFIELD GEOCACHE_CONTAINER, "", "/%-.4s ", "no_delim_before,optional" +OFIELD GEOCACHE_DIFF, "", "(%3.1f", "no_delim_before,optional" +OFIELD GEOCACHE_TERR, "", "/%3.1f)", "no_delim_before,optional" OFIELD DESCRIPTION, "", "%-.50s" - diff --git a/gpsbabel/xcsv.c b/gpsbabel/xcsv.c index e74b184a7..5f45170cb 100644 --- a/gpsbabel/xcsv.c +++ b/gpsbabel/xcsv.c @@ -396,6 +396,9 @@ xcsv_parse_style_line(const char *sbuff) if (strstr(s, "absolute")) { options |= OPTIONS_ABSOLUTE; } + if (strstr(s, "optional")) { + options |= OPTIONS_OPTIONAL; + } default: break; } -- 2.30.2